﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>



//int main()
//{
//	int a = 10000;
//	//00000000 00000000 00100111 00010000
//	//00       00       27       10
//	//内存 0x00002710
//	FILE* pf = fopen("test.txt", "wb");
//
//	fwrite(&a, 4, 1, pf);
//
//	fclose(pf);
//	pf = NULL;
//
//
//	return 0;
//}


//文件的打开和关闭
// ⽂件指针
// 每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区这些信息是保存在⼀个结构体变量中的。该结构体类型是由系
//这些信息是保存在⼀个结构体变量中的。该结构体类型是由系
//统声明的，取名 FILE

// struct _iobuf {
//	char* _ptr;
//	int _cnt;
//	char* _base;
//	int _flag;
//	int _file;
//	int _charbuf;
//	int _bufsiz;
//	char* _tmpfname;
//};
//typedef struct _iobuf FILE;


//通过⽂件指针变量能够间接找到与它关联的⽂件
//int main()
//{
//	//打开文件
//	FILE* fopen(const char* filename, const char* mode);
// 
//  //关闭文件
//  int fclose ( FILE * stream );
//                
//	FILE* pf;//文件指针变量
//
//	return 0;
//}

//int main()
//{
//	FILE* pf = fopen("data.txt", "w");
//	//文件的相对路径
//	//  .  -- 表示的是当前目录
//	//  ..   -- 上一级目录
//	//打开失败会放回NULL
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	//打开成功
//
//	//写文件
//
//	//关闭文件
//	fclose(pf);
//	//这里之后pf就是野指针了
//	pf = NULL;
//
//	return 0;
//}



//⽂件的顺序读写
//int main()
//{
//	FILE* pf= fopen("data.txt", "w");
//
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	//fputc('x', pf);
//	//fputc('y', pf);
//	//fputc('z', pf);
//	char c = 0;
//	for (c = 'a'; c <= 'z'; c++)
//	{
//		//字符输出函数
//		fputc(c, pf);
//	}
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//
//int main()
//{
//	FILE* pf= fopen("data.txt", "r");//abcedfg
//
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	//读文件
//	//返回读到字符的阿斯克码值
//	//读取失败返回EOF（-1）
//	//顺序读的方式
//	//int c = fgetc(pf);
//	//printf("%c ", c);//a
//	//
//	//c = fgetc(pf);
//	//printf("%c ", c);//b
//
//	//c = fgetc(pf);
//	//printf("%c ", c);//c
//
//	//c = fgetc(pf);
//	//printf("%c ", c);//d
//	int ch = 0;
//	while ((ch = fgetc(pf)) != EOF)
//	{
//		printf("%c ", ch);
//	}
//
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}


//int main()
//{
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//写字符串
//	//写一行
//	//本身不会换行
//	fputs("hello bit\n", pf);//\n换行
//	fputs("hello bit\n", pf);
//
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}



//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//读字符串
//
//	char str[100] = { 0 };
//	//fgets(str, 100, pf);//最多读四个，最后留一个给'\0'
//
//	//printf("%s\n", str);
//
//	//
//	//fgets(str, 20, pf);
//	//printf("%s\n", str);
//
//	while (fgets(str, 100, pf) != NULL)
//	{
//		printf("%s", str);
//	}
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}



//int main()
//{
//	int num = 100;
//	float score = 75.5;
//	char name[10] = "如花";
//
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	
//	fprintf(pf,"%d %f %s\n",num,score,name);
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}


//int main()
//{
//	int num = 0;
//	float score = 0;
//	char name[10] = { 0 };
//
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	
//	fscanf(pf,"%d %f %s",&num,&score,name);
//	printf("%d %f %s\n", num, score, name);
//
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}


//sprintf sscanf用在大型工程的序列化和发序列化
//int main()
//{
//	int num = 100;
//	float s = 3.14f;
//	char name[10] = "小强";
//
//	char str[100] = { 0 };
//
//	sprintf(str, "%d %f %s", num, s, name);
//	printf("字符串形式打印 %s\n", str);
//
//
//	int num1 = 0;
//	float s1 = 0.0;
//	char name1[10] = { 0 };
//	
//	sscanf(str, "%d %f %s",&num1,&s1,name1);//从字符串中提取数据
//	printf("格式化形式打印 %d %f %s", num1, s1, name1);
//
//	return 0;
//}


//fread和fwrite
//int main()
//{
//	FILE* pf = fopen("data.txt", "wb");//二进制的写
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	int arr[] = { 1,2,3,4,5 };
//	//fwrite
//	//二进制的形式写
//	fwrite(arr, sizeof(arr[0]), 5, pf);
//
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}




//fread是可以读取二进制信息的
//int main()
//{
//	FILE* pf = fopen("data.txt", "rb");//二进制的写
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	int arr[5] = { 0 };
//	//fwrite
//	//二进制的形式写
//	int i = 0;
//	/*for (i = 0; i < 5; i++) 
//	{
//		fread(&arr[i], sizeof(arr[0]), 1, pf);
//	}*/
//
//	//for (i = 0; i < 5; i++)
//	//{
//	//	fread(arr + i, sizeof(arr[0]), 1, pf);
//	//}
//	
//	
//	while (fread(arr + i,sizeof(arr[0]), 1, pf))
//	{
//		printf("%d ",arr[i]);
//	}
//	
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}



//⽂件的随机读写
//fseek
//根据⽂件指针的位置和偏移量来定位⽂件指针（⽂件内容的光标）。
//int fseek ( FILE * stream, long int offset, int origin );
//                                    偏移量      起始位置
// fteel
//返回⽂件指针相对于起始位置的偏移量
// rewind
//让⽂件指针的位置回到⽂件的起始位置
//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	int ch = fgetc(pf);
//
//	printf("%c", ch);
//
//	//希望读到d
//	
//	//定位文件中光标位置
//	//fseek(pf,2,SEEK_CUR);//当前位置
//	//fseek(pf, 3, SEEK_SET);//起始位置
//	fseek(pf, -4, SEEK_END);//末尾位置
//	ch = fgetc(pf);
//	printf("%c", ch);
//
//	long int r = ftell(pf);
//	printf("%d\n", r);
//
//	rewind(pf);
//	ch = fgetc(pf);
//	printf("%c", ch);
//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}
//



//⽂件读取结束的判定
//牢记：在⽂件读取过程中，不能⽤feof函数的返回值直接来判断⽂件的是否结束。
//feof 的作⽤是：当⽂件读取结束的时候，判断是读取结束的原因是否是：遇到⽂件尾结束
//文件读取结束有两种原因
// 1. 遇到文件末尾（正常结束）
// 2. 文件读取失败

//⽂本⽂件读取是否结束，判断返回值是否为 EOF （ fgetc ），或者 NULL （ fgets ）
//• fgetc 判断是否为 EOF .
//• fgets 判断返回值是否为 NULL .
//⼆进制⽂件的读取结束判断，判断返回值是否⼩于实际要读的个数。
//fread判断返回值是否⼩于实际要读的个数。

//⽂本⽂件的例⼦
//int main(void)
//{
//	int c; // 注意：int，⾮char，要求处理EOF
//	FILE* fp = fopen("test.txt", "r");
//	if (!fp) {
//		perror("File opening failed");
//		return EXIT_FAILURE;
//	}
//	//fgetc 当读取失败的时候或者遇到⽂件结束的时候，都会返回EOF
//	while ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环
//	{
//		putchar(c);
//	}
//	//判断是什么原因结束的
//	if (ferror(fp))
//		puts("I/O error when reading");
//	else if (feof(fp))
//		puts("End of file reached successfully");
//	fclose(fp);
//}


//⼆进制⽂件的例⼦：
enum {
	SIZE_M = 5 
};
int main(void)
{
	double a[SIZE_M] = { 1.,2.,3.,4.,5. };
	FILE* fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式
	fwrite(a, sizeof* a, SIZE_M, fp); // 写 double 的数组
	fclose(fp);

	double b[SIZE_M];
	fp = fopen("test.bin", "rb");
	size_t ret_code = fread(b, sizeof * b, SIZE_M, fp); // 读 double 的数组
	if (ret_code == SIZE_M) 
	{
		puts("Array read successfully, contents: ");
		for (int n = 0; n < SIZE_M; ++n)
			printf("%f ", b[n]);
		putchar('\n');
	}
	else { // error handling
		if (feof(fp))
			printf("Error reading test.bin: unexpected end of file\n");
		else if (ferror(fp)) {
			perror("Error reading test.bin");
		}
	}
	fclose(fp);

	return 0;
}